home *** CD-ROM | disk | FTP | other *** search
/ The Utilities Experience / The Utilities Experience - Volume 1.iso / software / misc / o-z / x-windows / mesa-amiwin / widgets / src / glwdrawingarea.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-08  |  19.1 KB  |  616 lines

  1. /* GLwDrawingArea.c -- Mesa GL Widget for X11 Toolkit Programming
  2.    Copyright (C) 1995 by
  3.      Jeroen van der Zijp <jvz@cyberia.cfdrc.com>
  4.      Thorsten Ohl <Thorsten.Ohl@Physik.TH-Darmstadt.de>
  5.  
  6.    This library is free software; you can redistribute it and/or
  7.    modify it under the terms of the GNU Library General Public
  8.    License as published by the Free Software Foundation; either
  9.    version 2 of the License, or (at your option) any later version.
  10.  
  11.    This library is distributed in the hope that it will be useful,
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU Library General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU Library General Public
  17.    License along with this library; if not, write to the Free Software
  18.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  
  20.    $Id: GLwDrawingArea.c,v 1.19 1995/06/08 09:51:10 ohl Exp $
  21.  */
  22.  
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <stdarg.h>
  26. #include <assert.h>
  27. #include <math.h>
  28. #include <float.h>
  29. #include <X11/X.h>
  30. #include <X11/Xlib.h>
  31. #include <X11/IntrinsicP.h>
  32. #include <X11/StringDefs.h>
  33. #include <X11/Shell.h>
  34. #ifdef __GLX_MOTIF
  35. #include <Xm/XmP.h>
  36. #include <Xm/PrimitiveP.h>
  37. #include <GL/GLwMDrawAP.h>
  38. #else
  39. #include <X11/CoreP.h>
  40. #include <GL/GLwDrawAP.h>
  41. #endif
  42. #include <X11/Xatom.h>
  43. #include <X11/Xmu/StdCmap.h>  /* for XmuLookupStandardColormap */
  44.  
  45. #ifdef __GLX_MOTIF
  46. #define GLwDrawingAreaWidget      GLwMDrawingAreaWidget
  47. #define GLwDrawingAreaClassRec    GLwMDrawingAreaClassRec
  48. #define GLwDrawingAreaRec         GLwMDrawingAreaRec
  49. #define glwDrawingAreaClassRec    glwMDrawingAreaClassRec
  50. #define glwDrawingAreaWidgetClass glwMDrawingAreaWidgetClass
  51. #endif
  52.  
  53. /* Actions */
  54.  
  55. static void glwInput (Widget w, XEvent * event, String * params, Cardinal * numParams);
  56.  
  57.  
  58. /* Methods */
  59.  
  60. static void ClassInitialize (void);
  61. static void Initialize (GLwDrawingAreaWidget req, GLwDrawingAreaWidget new,
  62.             ArgList args, Cardinal * num_args);
  63. static void Realize (Widget w, Mask * valueMask, XSetWindowAttributes * attributes);
  64. static void Redraw (GLwDrawingAreaWidget w, XEvent * event, Region region);
  65. static void Resize (GLwDrawingAreaWidget glw);
  66. static void Destroy (GLwDrawingAreaWidget glw);
  67.  
  68.  
  69. /* Translations */
  70.  
  71. static char defaultTranslations[] =
  72. "<KeyDown>:   glwInput() \n\
  73.    <KeyUp>:     glwInput() \n\
  74.    <BtnDown>:   glwInput() \n\
  75.    <BtnUp>:     glwInput() \n\
  76.    <BtnMotion>: glwInput() ";
  77.  
  78.  
  79. static XtActionsRec actions[] =
  80. {
  81.   {"glwInput", (XtActionProc) glwInput},    /* key or mouse input */
  82. };
  83.  
  84. static XtResource resources[] =
  85. {
  86. #undef offset
  87. #define offset(_field) XtOffset (GLwDrawingAreaWidget, glwDrawingArea._field)
  88.   {GLwNattribList, GLwCAttribList, XtRPointer, sizeof (int *),
  89.    offset (attribList), XtRImmediate, (caddr_t) NULL},
  90.   {GLwNvisualInfo, GLwCVisualInfo, GLwRVisualInfo, sizeof (XVisualInfo *),
  91.    offset (visualInfo), XtRImmediate, (caddr_t) NULL},
  92.   {GLwNinstallColormap, GLwCInstallColormap, XtRBoolean, sizeof (Boolean),
  93.    offset (installColormap), XtRImmediate, (caddr_t) True},
  94.   {GLwNallocateBackground, GLwNallocateOtherColors, XtRBoolean, sizeof (Boolean),
  95.    offset (allocateBackground), XtRImmediate, (caddr_t) False},
  96.   {GLwNallocateOtherColors, GLwCAllocateColors, XtRBoolean, sizeof (Boolean),
  97.    offset (allocateOtherColors), XtRImmediate, (caddr_t) False},
  98.   {GLwNinstallBackground, GLwCInstallBackground, XtRBoolean, sizeof (Boolean),
  99.    offset (installBackground), XtRImmediate, (caddr_t) True},
  100.   {GLwNginitCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
  101.    offset (ginitCallback), XtRImmediate, (XtPointer) NULL},
  102.   {GLwNinputCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
  103.    offset (inputCallback), XtRImmediate, (XtPointer) NULL},
  104.   {GLwNresizeCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
  105.    offset (resizeCallback), XtRImmediate, (XtPointer) NULL},
  106.   {GLwNexposeCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
  107.    offset (exposeCallback), XtRImmediate, (XtPointer) NULL},
  108.   {GLwNbufferSize, GLwCBufferSize, XtRInt, sizeof (int),
  109.    offset (bufferSize), XtRImmediate, (caddr_t) 0},
  110.   {GLwNlevel, GLwCLevel, XtRInt, sizeof (int),
  111.    offset (level), XtRImmediate, (caddr_t) 0},
  112.   {GLwNrgba, GLwCRgba, XtRBoolean, sizeof (Boolean),
  113.    offset (rgba), XtRImmediate, (caddr_t) False},
  114.   {GLwNdoublebuffer, GLwCDoublebuffer, XtRBoolean, sizeof (Boolean),
  115.    offset (doublebuffer), XtRImmediate, (caddr_t) False},
  116.   {GLwNstereo, GLwCStereo, XtRBoolean, sizeof (Boolean),
  117.    offset (stereo), XtRImmediate, (caddr_t) False},
  118.   {GLwNauxBuffers, GLwCAuxBuffers, XtRInt, sizeof (int),
  119.    offset (auxBuffers), XtRImmediate, (caddr_t) 0},
  120.   {GLwNredSize, GLwCColorSize, XtRInt, sizeof (int),
  121.    offset (redSize), XtRImmediate, (caddr_t) 1},
  122.   {GLwNgreenSize, GLwCColorSize, XtRInt, sizeof (int),
  123.    offset (greenSize), XtRImmediate, (caddr_t) 1},
  124.   {GLwNblueSize, GLwCColorSize, XtRInt, sizeof (int),
  125.    offset (blueSize), XtRImmediate, (caddr_t) 1},
  126.   {GLwNalphaSize, GLwCAlphaSize, XtRInt, sizeof (int),
  127.    offset (alphaSize), XtRImmediate, (caddr_t) 0},
  128.   {GLwNdepthSize, GLwCDepthSize, XtRInt, sizeof (int),
  129.    offset (depthSize), XtRImmediate, (caddr_t) 0},
  130.   {GLwNstencilSize, GLwCStencilSize, XtRInt, sizeof (int),
  131.    offset (stencilSize), XtRImmediate, (caddr_t) 0},
  132.   {GLwNaccumRedSize, GLwCAccumColorSize, XtRInt, sizeof (int),
  133.    offset (accumRedSize), XtRImmediate, (caddr_t) 0},
  134.   {GLwNaccumGreenSize, GLwCAccumColorSize, XtRInt, sizeof (int),
  135.    offset (accumGreenSize), XtRImmediate, (caddr_t) 0},
  136.   {GLwNaccumBlueSize, GLwCAccumColorSize, XtRInt, sizeof (int),
  137.    offset (accumBlueSize), XtRImmediate, (caddr_t) 0},
  138.   {GLwNaccumAlphaSize, GLwCAccumAlphaSize, XtRInt, sizeof (int),
  139.    offset (accumAlphaSize), XtRImmediate, (caddr_t) 0},
  140. #ifdef __GLX_MOTIF
  141.   {XmNtraversalOn, XmCTraversalOn, XmRBoolean, sizeof (Boolean),
  142.    XtOffset (GLwDrawingAreaWidget, primitive.traversal_on),
  143.    XmRImmediate, (XtPointer) FALSE},
  144.   {XmNhighlightOnEnter, XmCHighlightOnEnter, XmRBoolean, sizeof (Boolean),
  145.    XtOffset (GLwDrawingAreaWidget, primitive.highlight_on_enter),
  146.    XmRImmediate, (XtPointer) FALSE},
  147.   {XmNhighlightThickness, XmCHighlightThickness,
  148.    XmRHorizontalDimension, sizeof (Dimension),
  149.    XtOffset (GLwDrawingAreaWidget, primitive.highlight_thickness),
  150.    XmRImmediate, (XtPointer) 0},
  151. #endif
  152.   {GLwNdebug, GLwCDebug, XtRBoolean, sizeof (Boolean),
  153.    offset (debug), XtRImmediate, (caddr_t) False},
  154. #undef offset
  155. };
  156.  
  157.  
  158. GLwDrawingAreaClassRec glwDrawingAreaClassRec =
  159. {
  160.   {                /* Core fields */
  161. #ifdef __GLX_MOTIF
  162.     /* superclass               */ (WidgetClass) & xmPrimitiveClassRec,
  163.     /* class_name               */ "GLwMDrawingArea",
  164. #else
  165.     /* superclass               */ (WidgetClass) & coreClassRec,
  166.     /* class_name               */ "GLwDrawingArea",
  167. #endif
  168.     /* widget_size              */ sizeof (GLwDrawingAreaRec),
  169.     /* class_initialize         */ ClassInitialize,
  170.     /* class_part_initialize    */ NULL,
  171.     /* class_inited             */ FALSE,
  172.     /* initialize               */ (XtInitProc) Initialize,
  173.     /* initialize_hook          */ NULL,
  174.     /* realize                  */ Realize,
  175.     /* actions                  */ actions,
  176.     /* num_actions              */ XtNumber (actions),
  177.     /* resources                */ resources,
  178.     /* num_resources            */ XtNumber (resources),
  179.     /* xrm_class                */ NULLQUARK,
  180.     /* compress_motion          */ TRUE,
  181.     /* compress_exposure        */ TRUE,
  182.     /* compress_enterleave      */ TRUE,
  183.     /* visible_interest         */ TRUE,
  184.     /* destroy                  */ (XtWidgetProc) Destroy,
  185.     /* resize                   */ (XtWidgetProc) Resize,
  186.     /* expose                   */ (XtExposeProc) Redraw,
  187.     /* set_values               */ NULL,
  188.     /* set_values_hook          */ NULL,
  189.     /* set_values_almost        */ XtInheritSetValuesAlmost,
  190.     /* get_values_hook          */ NULL,
  191.     /* accept_focus             */ NULL,
  192.     /* version                  */ XtVersion,
  193.     /* callback_private         */ NULL,
  194.     /* tm_table                 */ defaultTranslations,
  195.     /* query_geometry           */ XtInheritQueryGeometry,
  196.     /* display_accelerator      */ XtInheritDisplayAccelerator,
  197.     /* extension                */ NULL
  198.   },
  199. #ifdef __GLX_MOTIF
  200.   {                /* XmPrimitive fields */
  201.     /* border_highlight         */ (XtWidgetProc) _XtInherit,
  202.     /* border_unhighlight       */ (XtWidgetProc) _XtInherit,
  203.     /* translations             */ XtInheritTranslations,
  204.     /* arm_and_activate         */ NULL,
  205.     /* get_resources            */ NULL,
  206.     /* num get_resources        */ 0,
  207.     /* extension                */ NULL,
  208.   }
  209. #endif /* __GLX_MOTIF */
  210. };
  211.  
  212. WidgetClass glwDrawingAreaWidgetClass = (WidgetClass) & glwDrawingAreaClassRec;
  213.  
  214.  
  215. static void
  216. error (Widget w, char *string)
  217. {
  218.   char buf[256];
  219.   sprintf (buf, "%s: %s: %s\n",
  220.        XtClass(w)->core_class.class_name, w->core.name, string);
  221.   XtAppError (XtWidgetToApplicationContext (w), buf);
  222. }
  223.  
  224. static void
  225. warning (Widget w, char *string)
  226. {
  227.   char buf[256];
  228.   sprintf (buf, "%s: %s: %s\n",
  229.        XtClass(w)->core_class.class_name, w->core.name, string);
  230.   XtAppWarning (XtWidgetToApplicationContext (w), buf);
  231. }
  232.  
  233. static Widget
  234. toplevel_widget (Widget w)
  235. {
  236.   Widget p;
  237.   for (p = XtParent (w); !XtIsShell (p); p = XtParent (p))
  238.     if (p == NULL)
  239.       {
  240.     p = w;
  241.     error (w, "can't find shell widget");
  242.       }
  243.   return p;
  244. }
  245.  
  246. /* Create attribute list for passing to glxChooseVisual()
  247.    from the ressources.  */
  248.  
  249. #define ATTRIBLIST_SIZE 30
  250. static void
  251. generate_attrib_list (GLwDrawingAreaPart *p)
  252. {
  253.   int i = 0;
  254.   p->attribList = (int *) XtCalloc (ATTRIBLIST_SIZE, sizeof (int));
  255.   p->attribList_allocated = True;
  256.  
  257.   p->attribList[i++] = GLX_BUFFER_SIZE;
  258.   p->attribList[i++] = p->bufferSize;
  259.   p->attribList[i++] = GLX_LEVEL;
  260.   p->attribList[i++] = p->level;
  261.   if (p->rgba)
  262.     p->attribList[i++] = GLX_RGBA;
  263.   if (p->doublebuffer)
  264.     p->attribList[i++] = GLX_DOUBLEBUFFER;
  265.   if (p->stereo)
  266.     p->attribList[i++] = GLX_STEREO;
  267.   p->attribList[i++] = GLX_AUX_BUFFERS;
  268.   p->attribList[i++] = p->auxBuffers;
  269.   p->attribList[i++] = GLX_RED_SIZE;
  270.   p->attribList[i++] = p->redSize;
  271.   p->attribList[i++] = GLX_GREEN_SIZE;
  272.   p->attribList[i++] = p->greenSize;
  273.   p->attribList[i++] = GLX_BLUE_SIZE;
  274.   p->attribList[i++] = p->blueSize;
  275.   p->attribList[i++] = GLX_ALPHA_SIZE;
  276.   p->attribList[i++] = p->alphaSize;
  277.   p->attribList[i++] = GLX_DEPTH_SIZE;
  278.   p->attribList[i++] = p->depthSize;
  279.   p->attribList[i++] = GLX_STENCIL_SIZE;
  280.   p->attribList[i++] = p->stencilSize;
  281.   p->attribList[i++] = GLX_ACCUM_RED_SIZE;
  282.   p->attribList[i++] = p->accumRedSize;
  283.   p->attribList[i++] = GLX_ACCUM_GREEN_SIZE;
  284.   p->attribList[i++] = p->accumGreenSize;
  285.   p->attribList[i++] = GLX_ACCUM_BLUE_SIZE;
  286.   p->attribList[i++] = p->accumBlueSize;
  287.   p->attribList[i++] = GLX_ACCUM_ALPHA_SIZE;
  288.   p->attribList[i++] = p->accumAlphaSize;
  289.   p->attribList[i++] = None;
  290. }
  291.  
  292. static Colormap
  293. get_standard_rgb_map (Widget w, XVisualInfo *vi)
  294. {
  295.   Display *dpy;
  296.   int scr;
  297.  
  298.   Colormap cmap;
  299.   XStandardColormap *std_cmaps;
  300.   int i, num_cmaps;
  301.  
  302.   dpy = XtDisplay (w);
  303.   scr = XScreenNumberOfScreen (XtScreen (w));
  304.  
  305.   cmap = None;
  306.   
  307.   if (XmuLookupStandardColormap (dpy, vi->screen, vi->visualid, vi->depth,
  308.                  XA_RGB_DEFAULT_MAP, False, True))
  309.     if (XGetRGBColormaps (dpy, RootWindow (dpy, scr),
  310.               &std_cmaps, &num_cmaps, XA_RGB_DEFAULT_MAP))
  311.       {
  312.     for (i = 0; i < num_cmaps; i++)
  313.       if (std_cmaps[i].visualid == vi->visualid)
  314.         {
  315.           cmap = std_cmaps[i].colormap;
  316.           break;
  317.         }
  318.     XFree (std_cmaps);
  319.       }
  320.   return cmap;
  321. }
  322.  
  323. #define glw_cmaps glwDrawingAreaClassRec.glwDrawingArea_class.colormaps
  324.  
  325. static Colormap
  326. lookup_colormap (Widget w, XVisualInfo *vi, int alloc)
  327. {
  328.   Display *dpy;
  329.   int scr;
  330.   Colormap cmap;
  331.   int i;
  332.  
  333.   LOG (w);
  334.  
  335.   dpy = XtDisplay (w);
  336.   scr = XScreenNumberOfScreen (XtScreen (w));
  337.   cmap = None;
  338.  
  339. #ifdef DEBUG
  340.   if (GLwDebug(w))
  341.     fprintf (stderr,
  342.          "looking up colormap for visual id #%ld on display #%p ... ",
  343.          vi->visualid, dpy);
  344. #endif
  345.  
  346.   assert (glw_cmaps.entries);
  347.   
  348.   for (i = 0; i < glw_cmaps.next_entry; i++)
  349.     if ((glw_cmaps.entries[i].dpy == dpy)
  350.     && (glw_cmaps.entries[i].vid == vi->visualid))
  351.       {
  352. #ifdef DEBUG
  353.     if (GLwDebug(w))
  354.       fprintf (stderr, "found #%ld\n", glw_cmaps.entries[i].cmap);
  355. #endif
  356.     return glw_cmaps.entries[i].cmap;
  357.       }
  358.  
  359.   if ((vi->class == TrueColor)
  360.       || (vi->class == DirectColor))
  361.     cmap = get_standard_rgb_map (w, vi);
  362.  
  363.   if (cmap == None)
  364.     cmap = XCreateColormap (dpy, RootWindow (dpy, scr), vi->visual, AllocNone);
  365.  
  366.   if (!cmap)
  367.       error (w, "can't get a colormap");
  368.  
  369.   if (glw_cmaps.next_entry >= glw_cmaps.allocated_entries)
  370.     {
  371.       glw_cmaps.allocated_entries += 10;
  372.       glw_cmaps.entries = (struct cmap_cache_entry *)
  373.     XtRealloc ((char *) glw_cmaps.entries,
  374.            glw_cmaps.allocated_entries
  375.            * sizeof (struct cmap_cache_entry));
  376.     }
  377.   
  378.   i = glw_cmaps.next_entry++;
  379.   glw_cmaps.entries[i].dpy = dpy;
  380.   glw_cmaps.entries[i].vid = vi->visualid;
  381.   glw_cmaps.entries[i].cmap = cmap;
  382.  
  383. #ifdef DEBUG
  384.   if (GLwDebug(w))
  385.     fprintf (stderr, "allocated new #%ld\n", cmap);
  386. #endif
  387.   return cmap;
  388. }
  389.  
  390. /* Inform the window manager that the widget W's window needs a
  391.    special colormap by setting the WM_COLORMAP_WINDOWS property
  392.    on the top level shell.
  393.  
  394.    FIXME: we should use XGetWMColormapWindows () to check for
  395.           other windows and add our window to this list instead
  396.       of overwriting. */
  397.  
  398. static void
  399. post_colormap (Widget w)
  400. {
  401.   Widget top = toplevel_widget (w);
  402.   Window wlist[2];
  403.   wlist[0] = XtWindow(w);
  404.   wlist[1] = XtWindow(top);
  405.   if (!XSetWMColormapWindows (XtDisplay(top), XtWindow(top), wlist, 2))
  406.     warning (w, "can't post colormap");
  407. }
  408.  
  409.  
  410.  
  411. /* Widget methods.  */
  412.  
  413. /* Initialize this widget class.  Currently we just allocate the first
  414.    chunk of memory for the colormap cache.  */
  415.  
  416. static void
  417. ClassInitialize (void)
  418. {
  419.   /* two's a crowd ...  (for most applications)  */
  420.   glw_cmaps.allocated_entries = 2;
  421.   glw_cmaps.next_entry = 0;
  422.   glw_cmaps.entries = (struct cmap_cache_entry *)
  423.     XtMalloc (glw_cmaps.allocated_entries * sizeof (struct cmap_cache_entry));
  424. }
  425.  
  426. /* Initialize a widget instance.
  427.    Here's where we do the colormap dance. */
  428.  
  429. static void 
  430. Initialize (GLwDrawingAreaWidget req,
  431.         GLwDrawingAreaWidget new,
  432.         ArgList args, Cardinal *num_args)
  433. {
  434.   Display *dpy;
  435.   int scr;
  436.   XVisualInfo *vi;
  437.  
  438.   LOG (new);
  439.   
  440.   dpy = XtDisplay (new);
  441.   scr = XScreenNumberOfScreen (XtScreen (new));
  442.  
  443.   if (req->core.width == 0)
  444.     new->core.width = 100;
  445.   if (req->core.height == 0)
  446.     new->core.width = 100;
  447.  
  448.   new->glwDrawingArea.attribList_allocated = False;
  449.   new->glwDrawingArea.visualInfo_allocated = False;
  450.  
  451.   vi = new->glwDrawingArea.visualInfo;
  452.  
  453.   /* If there's no visual in the resources, we have to select our own,
  454.      based on the attribute list or the other resources.  */
  455.  
  456.   if (vi == NULL)
  457.     {
  458.       /* If the list of attribues is not defined in the resources, we
  459.      have to build one from the other resources.  */
  460.       if (new->glwDrawingArea.attribList == NULL)
  461.     generate_attrib_list (&new->glwDrawingArea);
  462.  
  463.       /* Select the visual and remember it.  */
  464.       vi = glXChooseVisual (dpy, scr, new->glwDrawingArea.attribList);
  465.       if (!vi)
  466.     error ((Widget) new, "can't get a visual");
  467.       new->glwDrawingArea.visualInfo = vi;
  468.       new->glwDrawingArea.visualInfo_allocated = True;
  469.     }
  470.  
  471.   new->core.depth = vi->depth;
  472.  
  473.   /* If we're rendering in the default visual in color-index mode,
  474.      we continue to use the default map.  This is the most economical
  475.      approach.  In RGBA mode we try to use a standard RGB map for
  476.      TrueColor and DirectColor visuals.  If this is not available
  477.      and for all other visuals, we allocate a fresh colormap. */
  478.  
  479.   if (!new->glwDrawingArea.rgba
  480.       && (vi->visualid == XVisualIDFromVisual (DefaultVisual (dpy, scr))))
  481.     new->core.colormap = DefaultColormap (dpy, scr);
  482.   else
  483.     new->core.colormap = lookup_colormap ((Widget) new, vi, AllocNone);
  484. }
  485.  
  486. /* Realize a widget.
  487.    That's trivial, we just create the window with the appropriate
  488.    visual and call the callback functions.  */
  489.  
  490. static void 
  491. Realize (Widget w, Mask *mask, XSetWindowAttributes *attr)
  492. {
  493.   GLwDrawingAreaWidget glw;
  494.   Display *dpy;
  495.   int scr;
  496.   GLwDrawingAreaCallbackStruct cb;
  497.  
  498.   LOG (w);
  499.  
  500.   glw = (GLwDrawingAreaWidget) w;
  501.   dpy = XtDisplay (w);
  502.   scr = XScreenNumberOfScreen (XtScreen (w));
  503.  
  504.   /* Create the window.  */
  505.  
  506.   attr->colormap = w->core.colormap;
  507.   attr->event_mask
  508.     = KeyPressMask
  509.     | KeyReleaseMask
  510.     | ButtonPressMask
  511.     | ButtonReleaseMask
  512.     | EnterWindowMask
  513.     | LeaveWindowMask
  514.     | PointerMotionMask
  515.     | ButtonMotionMask
  516.     | ExposureMask
  517.     | StructureNotifyMask;
  518.   attr->border_pixel = BlackPixel (dpy, scr);
  519.   attr->background_pixel = BlackPixel (dpy, scr);
  520.   attr->backing_store = NotUseful;
  521.   *mask = CWColormap
  522.         | CWEventMask
  523.     | CWBorderPixel
  524.     | CWBackPixel
  525.     | CWBackingStore;
  526.   XtCreateWindow (w, (unsigned int) InputOutput,
  527.           glw->glwDrawingArea.visualInfo->visual,
  528.           *mask, attr);
  529.  
  530.   /* Install the colormap if requested.  */
  531.   if (glw->glwDrawingArea.installColormap)
  532.     post_colormap (w);
  533.  
  534.   /* Invoke callback to initialize.  */
  535.   cb.reason = GLwCR_GINIT;
  536.   cb.event = NULL;
  537.   cb.width = glw->core.width;
  538.   cb.height = glw->core.height;
  539.   XtCallCallbackList ((Widget) glw, glw->glwDrawingArea.ginitCallback, &cb);
  540. }
  541.  
  542. /* Invoke expose callbacks to redraw screen */
  543.  
  544. static void 
  545. Redraw (GLwDrawingAreaWidget w, XEvent * event, Region region)
  546. {
  547.   GLwDrawingAreaCallbackStruct cb;
  548.   LOG (w);
  549.   /* Ignore while not yet realized.  */
  550.   if (!XtIsRealized ((Widget) w))
  551.     return;
  552.   cb.reason = GLwCR_EXPOSE;
  553.   cb.event = event;
  554.   cb.width = w->core.width;
  555.   cb.height = w->core.height;
  556.   XtCallCallbackList ((Widget) w, w->glwDrawingArea.exposeCallback, &cb);
  557. }
  558.  
  559. /* Invoke resize callbacks */
  560.  
  561. static void 
  562. Resize (GLwDrawingAreaWidget glw)
  563. {
  564.   GLwDrawingAreaCallbackStruct cb;
  565.   LOG (glw);
  566.   /* Ignore while not yet realized.  */
  567.   if (!XtIsRealized ((Widget) glw))
  568.     return;
  569.   cb.reason = GLwCR_RESIZE;
  570.   cb.event = NULL;
  571.   cb.width = glw->core.width;
  572.   cb.height = glw->core.height;
  573.   XtCallCallbackList ((Widget) glw, glw->glwDrawingArea.resizeCallback, &cb);
  574. }
  575.  
  576. /* Window destroy handling.
  577.  
  578.    FIXME: shouldn't we remove the WM_COLORMAP_WINDOWS property
  579.           from the toplevel shell?  */
  580.  
  581. static void 
  582. Destroy (GLwDrawingAreaWidget glw)
  583. {
  584.   LOG (glw);
  585.   XtRemoveAllCallbacks ((Widget) glw, GLwNinputCallback);
  586.   XtRemoveAllCallbacks ((Widget) glw, GLwNresizeCallback);
  587.   XtRemoveAllCallbacks ((Widget) glw, GLwNexposeCallback);
  588.   if (glw->glwDrawingArea.attribList_allocated)
  589.     {
  590.       XtFree ((char *)glw->glwDrawingArea.attribList);
  591.       glw->glwDrawingArea.attribList_allocated = False;
  592.     }
  593.   if (glw->glwDrawingArea.visualInfo_allocated)
  594.     {
  595.       XtFree ((char *)glw->glwDrawingArea.visualInfo);
  596.       glw->glwDrawingArea.visualInfo_allocated = False;
  597.     }
  598. }
  599.  
  600. /* Action routine for keyboard and mouse events */
  601.  
  602. static void 
  603. glwInput (Widget w, XEvent * event, String * params, Cardinal * numParams)
  604. {
  605.   GLwDrawingAreaCallbackStruct cb;
  606.   GLwDrawingAreaWidget glw = (GLwDrawingAreaWidget) w;
  607.   LOG (w);
  608.   cb.reason = GLwCR_INPUT;
  609.   cb.event = event;
  610.   cb.width = glw->core.width;
  611.   cb.height = glw->core.height;
  612.   XtCallCallbackList ((Widget) glw, glw->glwDrawingArea.inputCallback, &cb);
  613. }
  614.  
  615. /* The End.  */
  616.